/*
This is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.

This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this software; if not, write to the Free
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA, or see the FSF site: http://www.fsf.org.

 
 */
using System;
using System.Web;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
using System.Text;
using System.IO.Compression;

namespace Org.Eurekaa.DNJ.Http
{


    public class DNJHttpModule : IHttpModule
    {
        private DNJFilter filter;
        public void Init(HttpApplication context)
        {
            context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);
//            context.EndRequest += new EventHandler(context_EndRequest);
        }

        public void Dispose() { }

        private void context_EndRequest(object sender, EventArgs e)
        {
            HttpResponse response = HttpContext.Current.Response;


            if (response.ContentType != "text/html") return;

            string str = filter != null ? filter.GetOutStr() : "";
            StringBuilder sbResp = new StringBuilder();
            if (HttpContext.Current != null && HttpContext.Current.Request != null && HttpContext.Current.Request.Form[ConstNames.DNJ_DefaultCssClass] != null)
            {

                MatchCollection jqmc = Regex.Matches(str, @"<!--\[" + ConstNames.DNJ_TAG + @"\]-->((.|\s)*?)<!--\[\/" + ConstNames.DNJ_TAG + @"\]-->", RegexOptions.Compiled | RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline);
                MatchCollection netmc = Regex.Matches(str, "<input.*name=\"(__EVENTVALIDATION|__VIEWSTATE|__EVENTARGUMENT|__EVENTTARGET)\".*>", RegexOptions.Compiled | RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline);

                foreach (Match m in jqmc)
                    sbResp.Append(m.Groups[1].Value);

                foreach (Match m in netmc)
                    sbResp.Append(m.Groups[0].Value);

                str = sbResp.ToString();
            }



            response.Write(str.Trim());

            this.filter.Dispose();

        }

        private void context_ReleaseRequestState(object sender, EventArgs e)
        {
            HttpResponse response = HttpContext.Current.Response;

            if (response.ContentType == "text/html")
            {
                //this.filter = new PageFilter(HttpContext.Current.Response.Filter);
                response.Filter = new PageFilter(HttpContext.Current.Response.Filter);
            }

        }
    }

    public class DNJFilter : MemoryStream
    {
        private Stream BaseStream = null;

        private StringBuilder outSB = null;

        public String GetOutStr()
        {
            return outSB.ToString();
        }

        public DNJFilter(Stream baseStream)
        {
            BaseStream = baseStream;
            outSB = new StringBuilder();
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            outSB.Append(UTF8Encoding.UTF8.GetString(buffer));
        }
    }

    public class PageFilter : MemoryStream
    {
        Stream responseStream;
        StringBuilder responseHtml;
        public PageFilter(Stream inputStream)
        {
            responseStream = inputStream;
            responseHtml = new StringBuilder();
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            if (HttpContext.Current == null || HttpContext.Current.Request == null || HttpContext.Current.Request.Form[ConstNames.DNJ_DefaultCssClass] == null)
            {
                responseStream.Write(buffer, offset, count);
                return;
                //return base
            }
            string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);

            // ---------------------------------
            // Wait for the closing </html> tag
            // ---------------------------------
            Regex eof = new Regex("</html>", RegexOptions.IgnoreCase);

            if (!eof.IsMatch(strBuffer))
            {
                responseHtml.Append(strBuffer);
            }
            else
            {
                responseHtml.Append(strBuffer);
                string finalHtml = responseHtml.ToString();

                // Transform the response and write it back out

                StringBuilder sbResp = new StringBuilder();

                MatchCollection jqmc = Regex.Matches(finalHtml, @"<!--\[" + ConstNames.DNJ_TAG + @"\]-->((.|\s)*?)<!--\[\/" + ConstNames.DNJ_TAG + @"\]-->", RegexOptions.Compiled | RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline);
                MatchCollection netmc = Regex.Matches(finalHtml, "<input.*name=\"(__EVENTVALIDATION|__VIEWSTATE|__EVENTARGUMENT|__EVENTTARGET)\".*>", RegexOptions.Compiled | RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline);

                foreach (Match m in jqmc)
                    sbResp.Append(m.Groups[1].Value);

                foreach (Match m in netmc)
                    sbResp.Append(m.Groups[0].Value);

                finalHtml = sbResp.ToString();
                                
                byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);

                responseStream.Write(data, 0, data.Length);
            }

        }

    }
}